<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .container div {
      float: left;
      width: 100px;
      height: 100px;
      border-radius: 50%;
      border: 1px solid #ccc;
      margin: 0 5px;
      background: #ccc;
    }
    .container {
      width: 500px;
      height: 100px;
      margin: 300px auto;
    }
    .green.active {
      background: green;
    }
    .yellow.active {
      background: yellow;
    }
    .red.active {
      background: red;
    }
  </style>
  <body>
    <div class="container">
      <div class="green"></div>
      <div class="yellow"></div>
      <div class="red active"></div>
    </div>
  </body>
</html>
<script>
  // 需求：
  // 1.绿灯5秒之后=>黄灯
  // 2.黄灯3秒之后=>红灯
  // 3.红灯6秒之后=>绿灯
  //   获取元素
  let g = document.querySelector(".green");
  let y = document.querySelector(".yellow");
  let r = document.querySelector(".red");
  let dvs = document.querySelector(".container");
  //需要promise来处理交替效果，通过定时器来控制交替的时间
  //通过设置active类名让灯亮起来
  //   步骤
  // 1.封装一个promise函数，这里传入延时的时间，灯亮的元素
  function light(timer, dom) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        // console.log(dom);
        resolve(dom);
      }, timer);
    });
  }
  //2.
  function recursion() {
    Promise.resolve()
      .then(() => {
        console.log("绿灯亮");
        // 把绿灯div元素传入css函数
        css(g);
        return light(5000, y);
      })
      .then((res) => {
        //绿灯5秒之后亮黄灯
        console.log(res); //黄灯
        css(res);
        return light(3000, r);
      })
      .then((res) => {
        //黄灯3秒之后亮红灯
        console.log(res); //红灯
        css(res);
        return light(6000, g);
      })
      .then((res) => {
        //红灯6秒后两绿灯
        // console.log("亮绿灯");
        recursion();
      });
  }
  recursion();
  //3.再封装一个专门处理dom样式的函数
  function css(dom) {
    console.log(dom);
    //由于dom元素 类名加上active就能亮起来，所以操作类名就行了
    //先储存当前要设定的原本类名
    let className = dom.className;
    //排他，将其他元素的active类名干掉
    //获取其他元素
    //   console.log(dvs);
    [...dvs].forEach((div) => {
      // 获取div的类名，干掉active
      let className = div.className;
      // 干掉div的active类名
      className = className.replace(/\sactive/, "");
      div.className = className;
    });
    // 给当前元素加上active
    dom.className = className = " active";
  }
</script>
